package com.nearsoft.academy;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.util.AttributeSet;
import android.view.View;

import java.util.Timer;

/**
 * Created with IntelliJ IDEA.
 * User: Administrator
 * Date: 8/13/12
 * Time: 10:34 AM
 * To change this template use File | Settings | File Templates.
 */
public class VisualAid extends View {

    private final float NUMBER_OF_DIVISIONS = 16f;
    private final float DIVISION_ANGLE = 360f / NUMBER_OF_DIVISIONS;
    private final float MAX_PITCH = 30f;
    private final float PITCH_RELATIVE = MAX_PITCH * 2f;
    private final int ARROW_LENGTH = 100;

    private Point lineStart;
    private Point lineEnd;

    private Arrow horizontalArrow;
    private Arrow verticalArrow;

    public boolean isPhotoTime() {
        return photoTime;
    }

    public void setPhotoTime(boolean photoTime) {
        this.photoTime = photoTime;
    }

    private boolean photoTime;



    private float circleCX = 0;
    private float circleCY = 0;
    private final float CIRCLE_RADIUS = 50;

    private Paint linePaint;
    private Paint arrowPaint;
    private Paint circlePaint;
    private Paint textPaint;

    private float initialAzimuth = 0;
    private float nextTargetAzimuth = 0;

    private boolean isCaptureActive;
    private boolean isPathCompleted = false;

    private float azimuthDifference = 0;

    private float azimuth = 0;
    private float Pitch = 0;
    private float Roll = 0;

    private Timer tmr;
    private boolean timerIsRunning;
    private CounterTask _counterTask = new CounterTask();


    public VisualAid(Context context, AttributeSet attrs){
        super(context, attrs);
        initPaints();
        tmr = new Timer();
        lineStart = new Point();
        lineEnd = new Point();
    }



    private void initPaints(){
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(Color.RED);
        linePaint.setAlpha(200);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setStrokeWidth(3);

        arrowPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        arrowPaint.setColor(Color.BLUE);
        arrowPaint.setAlpha(200);
        arrowPaint.setStyle(Paint.Style.STROKE);
        arrowPaint.setStrokeWidth(10);

        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaint.setColor(Color.GREEN);
        circlePaint.setAlpha(200);
        circlePaint.setStyle(Paint.Style.FILL);

        textPaint = new Paint(Paint.DEV_KERN_TEXT_FLAG);
        textPaint.setColor(Color.BLACK);
        textPaint.setTextSize(textPaint.measureText("Yy"));

        //ARROW_LENGTH = getWidth() / 5f;
    }

    public void startCapture() {
        setInitialAzimuth(this.azimuth);
        nextTargetAzimuth = Graphics.angleSum(this.azimuth, DIVISION_ANGLE);
        setCaptureActive(true);
        timerIsRunning = false;
    }

    public void stopCapture() {
        setCaptureActive(false);
    }

    public boolean getPathCompleted() {
        return isPathCompleted;
    }

    public boolean getCaptureActive() {
        return isCaptureActive;
    }
    private void setCaptureActive(boolean value) {
        this.isCaptureActive = value;
    }

    private float getInitialAzimuth() {
        return initialAzimuth;
    }
    private void setInitialAzimuth(float value) {
        this.initialAzimuth = value;
    }

    public float getAzimuth(){
        return  this.azimuth;
    }
    public void setAzimuth(float value){
        this.azimuth = value;
    }

    public float getPitch(){
        return Pitch;
    }
    public void setPitch(float pitch){
        Pitch = pitch;
    }

    public float getRoll(){
        return Roll;
    }
    public void setRoll(float roll){
        Roll = roll;
    }

    public float getAzimuthDifference() {
        return azimuthDifference;
    }

    private void moveToNextTarget() {
        nextTargetAzimuth = Graphics.correctAngle(nextTargetAzimuth + DIVISION_ANGLE);
    }


    @Override
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    public void onDraw(Canvas canvas){
        super.onDraw(canvas);

        updateDrawingValues();
        // Pitch line
        canvas.drawLine(lineStart.x, lineStart.y, lineEnd.x, lineEnd.y, linePaint);

        if (isCaptureActive){
            if (Math.abs(azimuthDifference) < 2){
                // Position is correct. Draw green circle.
                canvas.drawCircle(circleCX, circleCY, CIRCLE_RADIUS, circlePaint);
                // Count 1 sec to go to the next point
                if (!timerIsRunning){
                    timerIsRunning = true;
                    _counterTask = new CounterTask();
                    tmr = new Timer();
                    //_counterTask.setIsCompleted(false);
                    tmr.schedule(_counterTask, 1000, 1000);
                } else {
                    if(_counterTask.isCompleted()) {
                        setPhotoTime(true);
                        moveToNextTarget();
                        tmr.cancel();
                        timerIsRunning = false;
                    }
                }

            }
            else {
                tmr.cancel();
                timerIsRunning = false;
                canvas.drawLine(horizontalArrow.getStart().x, horizontalArrow.getStart().y, horizontalArrow.getEnd().x, horizontalArrow.getEnd().y, arrowPaint);
                canvas.drawLine(horizontalArrow.getEnd().x, horizontalArrow.getEnd().y, horizontalArrow.getLeft().x, horizontalArrow.getLeft().y, arrowPaint);
                canvas.drawLine(horizontalArrow.getEnd().x, horizontalArrow.getEnd().y, horizontalArrow.getRight().x, horizontalArrow.getRight().y, arrowPaint);
            }
        }
    }

    private void updateDrawingValues(){
        float width = getWidth();
        float height = getHeight();

        // Get pitch for graphics
        float pitch;
        if (this.Pitch > MAX_PITCH){
            pitch = MAX_PITCH;
        }
        else if (this.Pitch < -MAX_PITCH){
            pitch = 0 - MAX_PITCH;
        }
        else {
            pitch = this.Pitch;
            if (pitch > -3 && pitch < 3)
                linePaint.setColor(Color.GREEN);
            else
                linePaint.setColor(Color.RED);
        }

        pitch = MAX_PITCH - pitch;

        // Pitch line positions
        this.lineEnd.x = (int)width;
        this.lineStart.y = (int)(pitch * getHeight() / PITCH_RELATIVE);
        this.lineEnd.y = getHeight() - lineStart.y;

        if (isCaptureActive){
            circleCX = width / 2;
            circleCY = height / 2;

            Point start = new Point(0, 0);
            Point end = new Point(0, 0);

            // Distance from the destination Azimuth angle to the current Azimuth angle
            azimuthDifference = Graphics.angleSubtraction(nextTargetAzimuth, this.azimuth);

            if (azimuthDifference > DIVISION_ANGLE / 2f) {
                // very right
                end.x = getWidth();
            }
            else if (azimuthDifference < -DIVISION_ANGLE / 2f) {
                // very left
                end.x = 0;
            }
            else {
                // right
                end.x = (int)((getWidth()/2f) * (1 + (azimuthDifference/(DIVISION_ANGLE/2f))));
            }

            float slope = Graphics.getLineSlope(lineStart.x, lineStart.y, lineEnd.x, lineEnd.y);
            if (azimuthDifference >= 0) {
                // nextTargetAzimuth is on the right
                start.x = end.x - ARROW_LENGTH;
            }
            else
            {
                // nextTargetAzimuth is on the left
                start.x = end.x + ARROW_LENGTH;
            }

            end.y = (int)(Graphics.getYFromX(end.x, slope, lineStart.y));
            start.y = (int)Graphics.getYFromX(start.x, slope, lineStart.y);
            this.horizontalArrow = new Arrow(start, end);
            // azimuth arrow positions
        }

    }



}
